import React from 'react'
import _ from 'lodash'
import { requireAll } from 'common/util'
import { Switch, Route, Redirect, withRouter } from 'react-router-dom'
import { connect } from 'react-redux'
import store from './store'
// import './styles/global/layout.styl'

const Default = () => <div>hello</div>

const roots = [
    {
        path: '/project/:id/:tab(issue|plan)',
        component: withRouter({})(Default),
        subs: [
            {
                path: '/issue',
                component: () => <h1>Issue</h1>,
            },
            {
                path: '/plan',
                component: () => <h1>Plan</h1>,
            },
        ],
    },
    {
        path: '/restricted',
        component: 'NoAuthority',
        meta: {
            visible: false,
        },
    },
]

// genetate routes and links
const containers = requireAll(require.context('container', true, /^(.(?!App))+\.js$/))

const autoConnect = containerSet => {
    _.toPairs(containerSet).forEach(([key, value]) => {
        if (typeof value === 'object') {
            autoConnect(value)
        } else {
            const { propSelectors, defaultProps } = value
            if (!propSelectors) {
                return
            }
            const mapStateToProps = state => {
                const rs = _.chain(propSelectors)
                    .toPairs()
                    .map(([alias, k]) => {
                        let v = _.get(state, k, defaultProps[alias])
                        if (_.isObject(v)) {
                            v = {
                                ...defaultProps[alias],
                                ...v,
                            }
                        }
                        return [alias, v]
                    })
                    .fromPairs()
                    .value()
                return rs
            }

            containerSet[key] = connect(mapStateToProps)(value)
        }
    })
}
autoConnect(containers)


const getComponent = ({ path, component, subs }) => {
    let comp = null
    if (component) {
        if (typeof component === 'function') {
            comp = component
        } else if (_.get(containers, component)) {
            comp = _.get(containers, component)
        } else {
            comp = containers._.Simple
        }
    } else {
        const parts = path.split('/').slice(1)
        if (subs) {
            comp = _.get(containers, [...parts, 'Index'], containers._.WithRoutes)
        } else {
            const tail = parts.pop()
            comp = _.get(containers, [...parts, _.capitalize(tail)], containers._.Simple)
        }
    }
    return comp
}

const __cache = new Map()
const mapViewToRoutes = ({ subs = [], path = '' }) => {
    if (__cache.has(path)) {
        return __cache.get(path)
    }

    const accessibleSubs = subs.filter(sub => ['*'].concat(store.getState()['APP.PERMISSION']).includes(_.get(sub, 'meta.access', '*')))
    const Routes = props => (
        <div {...props} id="area">
            <Switch>
                {
                    accessibleSubs.map(sub => ({ ...sub, path: path + sub.path })).map(sub => {
                        const Comp = getComponent(sub)
                        return (<Route
                            key={sub.path}
                            path={sub.path}
                            render={ps => <Comp {...ps} view={mapViewToRoutes(sub)} />}
                        />)
                    })
                }
                {
                    !!accessibleSubs.length && <Redirect from={path} to={path + accessibleSubs[0].path} />
                }
            </Switch>
        </div>
    )

    const routesAndLinks = {
        Routes, roots,
    }
    __cache.set(path, routesAndLinks)
    return routesAndLinks
}

export default mapViewToRoutes({ subs: roots })
